package com.indexingsystem.boss.filter;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.annotation.Resource;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AccountException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.ExcessiveAttemptsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.SimplePrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.context.annotation.Scope;

import com.indexingsystem.boss.Vo.AuthRoleVo;
import com.indexingsystem.boss.entity.Pusers;
import com.indexingsystem.boss.entity.Roles;
import com.indexingsystem.boss.token.manager.TokenManager;
import com.indexingsystem.boss.utils.ByteSourceUtils;
import com.indexingsystem.boss.utils.DateUtil;
import com.indexingsystem.system.service.IOperationsService;
import com.indexingsystem.system.service.IPusersService;
import com.indexingsystem.system.service.IRolesService;

/**
 * 用户登陆认证鉴权.
 */
@Scope(value = "prototype")
public class UserRealm extends AuthorizingRealm {

	@Resource
	private IOperationsService iOperationsService;

	@Resource
	private IRolesService iRolesService;

	@Resource
	private IPusersService iPusersService;
	
	@Override
    protected AuthorizationInfo doGetAuthorizationInfo(
            PrincipalCollection principals) throws LockedAccountException,ExcessiveAttemptsException{
	    String userId = TokenManager.getUserId();
        SimpleAuthorizationInfo info =  new SimpleAuthorizationInfo();
        //根据用户ID查询角色（role），放入到Authorization里。
        List<AuthRoleVo> authRoleVoList =  iRolesService.findRoleByUserId(userId);
        Set<String> roles = null;
        if(null != authRoleVoList && authRoleVoList.size()>0){
            roles = new HashSet<String>();
            for(AuthRoleVo authRoleVo:authRoleVoList){
                roles.add(authRoleVo.getRoleCode());
            }
        }        
        info.setRoles(roles);        
        //根据用户ID查询权限（permission），放入到Authorization里。
        List<AuthRoleVo> authFunctionRoleVoList =  iOperationsService.findPermissionByUserId(userId);
        Set<String> permissions = null;
        if(null != authFunctionRoleVoList && authFunctionRoleVoList.size()>0){
            permissions = new HashSet<String>();
            for(AuthRoleVo permissVo:authFunctionRoleVoList){
                permissions.add(permissVo.getUrl());
            }
        }
        info.setStringPermissions(permissions);       
        return info;       
    }
	
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws LockedAccountException,ExcessiveAttemptsException {	       
//        ShiroToken token = (ShiroToken) authcToken;
        UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) authcToken;
        String username = String.valueOf(usernamePasswordToken.getUsername());
        Pusers user = iPusersService.login(username);
        SimpleAuthenticationInfo simpleAuthentication = null;
        try {
        if (null == user) {
            throw new AccountException("帐号或密码不正确！");
            /**
             * 如果用户的status为禁用。那么就抛出<code>DisabledAccountException</code>
             */
        } else {
            if (Boolean.TRUE.equals(user.getLocked())) {
                throw new LockedAccountException("帐号已经禁止登录！"); // 帐号锁定
            }
            if (null != user && Boolean.FALSE.equals(user.getLocked())) {
                // 更新登录时间 last login time
                user.setLastLoginDate(DateUtil.parseFormatToDate(DateUtil.getCurTotalDate()));
                iPusersService.updatePuserInfo(user);
                
                simpleAuthentication = new SimpleAuthenticationInfo(
                        user.getUserName(), // 用户名
                        user.getPassword(), // 密码       
                        //ByteSourceUtils.deserialize(ByteSourceUtils.serialize(user.getSalt()),ByteSource.class),
                        getName()); // realm name                
                
                simpleAuthentication.setCredentialsSalt(ByteSourceUtils.bytes(username+user.getSalt()));            
             }          
           }
        }
        catch(ExcessiveAttemptsException e){
            e.printStackTrace();
        }catch (Exception e) {
            e.printStackTrace();
        }   
        return simpleAuthentication;
	}

	/**
	 * 添加角色
	 * 
	 * @param userId
	 * @param info
	 */
	private void addRole(String userId, SimpleAuthorizationInfo info) {
		List<Roles> roles = iRolesService.getRoleInfoByUserId(userId);
		if (roles != null && roles.size() > 0) {
			for (Roles role : roles) {
				info.addRole(role.getRoleName());
			}
		}
	}

    public void clearCachedAuthorizationInfo(){
        PrincipalCollection principalCollection = SecurityUtils.getSubject().getPrincipals();
        SimplePrincipalCollection principals = new SimplePrincipalCollection(principalCollection,
            getName());
        super.clearCachedAuthorizationInfo(principals);
    }

    /**
     * 指定principalCollection 清除
     */
    public void clearCachedAuthorizationInfo(PrincipalCollection principalCollection)
    {
        SimplePrincipalCollection principals = new SimplePrincipalCollection(principalCollection,
            getName());
        super.clearCachedAuthorizationInfo(principals);
    }
}